package com.honey.eclipse.formatter;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * 本类是读取eclipse的代码格式文件,用于使用JDT格式化java代码. 在eclipse菜单中 Window -> Preferences ->
 * Java -> Code Style ->Formatter<br/>
 * 设定代码格式化,然后导出,导出的xml文件用本类读取,JDT就会按照这个格式化方式格式化java代码.
 * 请主意profiles的version,低版本的version不被支持.
 * @author Administrator
 * 
 */
public class EclipseCodeFormatterConstants {
	
	private static Map<String, String> springCodeFormatterSettings = null;
	
	private static Map<String, String> camelCodeFormatterSettings = null;
	
	private static Map<String, String> cStyleFormatterSettings = null;
	
	/**
	 * 定制
	 * @return
	 */
	public static final Map<String, String> getCustomeEclipseDefaultSettings() {
		Map<String, String> map = DefaultCodeFormatterConstants.getEclipseDefaultSettings();
		map.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_6);  
		map.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_6);  
		map.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_6);  
		 
		map.put(// change the option to wrap each enum constant on a new line  
				DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ENUM_CONSTANTS,  
				DefaultCodeFormatterConstants.createAlignmentValue(  
						true,  
						DefaultCodeFormatterConstants.WRAP_ONE_PER_LINE,  
						DefaultCodeFormatterConstants.INDENT_ON_COLUMN
				)
		);
		return map ;
	}
	
	public static final Map<String, String> getJavaConventionsSettings() {
		Map<String, String> map = DefaultCodeFormatterConstants.getJavaConventionsSettings();
		map.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);  
		map.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);  
		map.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
		return map;
	}
	/**
	 * 获取eclipse默认的设定格式
	 * @return
	 */
	public static final Map<String, String> getEclipseDefaultSettings() {
		Map<String, String> map = DefaultCodeFormatterConstants.getEclipseDefaultSettings();
		map.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);  
		map.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);  
		map.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
		return map;
	}
	
	
	/**
	 * 加载指定格式文件
	 * @param settingsFile
	 * @return
	 */
	public static final Map<String, String> getLoadEclipseFormatterSettings(String settingsFile) {
		Map<String, String> eclipseCodeFormatterSettings =new HashMap<String, String>();
		try {
			InputStream in =new FileInputStream (settingsFile);
			eclipseCodeFormatterSettings = parserEclipseCodeFormatterSettingsFile(in);
		} catch (Exception e) {
		}
		return eclipseCodeFormatterSettings;
	}
	
	/**
	 * 获取Apache Camel 的代码格式化规范,(Settings文件在Apache Camel 的源码包中可以获取到)
	 * 
	 * @return
	 */
	public static final Map<String, String> getCamelCodeFormatterSettings() {
		if (camelCodeFormatterSettings == null) {
			InputStream in = EclipseCodeFormatterConstants.class.getResourceAsStream("CamelCodeFormatter.xml");
			try {
				camelCodeFormatterSettings = parserEclipseCodeFormatterSettingsFile(in);
				
			} catch (Exception e) {
			}
		}

		return camelCodeFormatterSettings;
	}
	
	
	/**
	 * 获取C/C++ 的代码格式化
	 * 
	 * @return
	 */
	public static final Map<String, String> getCCodeFormatterSettings() {
		if (cStyleFormatterSettings == null) {
			InputStream in = EclipseCodeFormatterConstants.class.getResourceAsStream("CStyleFormatter.xml");
			try {
				cStyleFormatterSettings = parserEclipseCodeFormatterSettingsFile(in);
				
			} catch (Exception e) {
			}
		}

		return cStyleFormatterSettings;
	}
	
	/**
	 * 获取Spring 的代码格式化规范,(Settings文件在spring的源码包中可以获取到)
	 * 
	 * @return
	 */
	public static final Map<String, String> getSpringCodeFormatterSettings() {
		if (springCodeFormatterSettings == null) {
			InputStream in = EclipseCodeFormatterConstants.class
					.getResourceAsStream("eclipse-code-formatter.xml");
			try {
				springCodeFormatterSettings = parserEclipseCodeFormatterSettingsFile(in);
			} catch (Exception e) {
			}
		}

		return springCodeFormatterSettings;
	}

	private static Map<String, String> parserEclipseCodeFormatterSettingsFile(
			InputStream settings) throws Exception {
		SAXHandler handler = new SAXHandler();
		SAXParserFactory saxparserfactory = SAXParserFactory.newInstance();
		SAXParser saxparser = saxparserfactory.newSAXParser();
		saxparser.parse(settings, handler);
		return handler.getSetting();
	}

	static class SAXHandler extends DefaultHandler {

		private Map<String, String> setting = null;

		public SAXHandler() {
			setting = new HashMap<String, String>();
		}

		@Override
		public void startElement(String uri, String localName, String name,
				Attributes attributes) throws SAXException {
			if ("setting".equalsIgnoreCase(name)) {
				String key = attributes.getValue("id");
				String value = attributes.getValue("value");
				if (key != null && key.length() > 0 && value != null
						&& value.length() > 0) {
					setting.put(key, value);
				}
			}
		}

		public Map<String, String> getSetting() {
			return setting;
		}
	}
}
